package org.example.autoactivationplugin;

import java.io.Serializable;
import java.util.UUID;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteCluster;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.cluster.ClusterState;
import org.apache.ignite.lang.IgnitePredicate;
import org.apache.ignite.plugin.CachePluginContext;
import org.apache.ignite.plugin.CachePluginProvider;
import org.apache.ignite.plugin.ExtensionRegistry;
import org.apache.ignite.plugin.IgnitePlugin;
import org.apache.ignite.plugin.PluginConfiguration;
import org.apache.ignite.plugin.PluginContext;
import org.apache.ignite.plugin.PluginProvider;
import org.apache.ignite.plugin.PluginValidationException;

/**
 * Activate cluster when specified condition meet
 *
 * @author user
 */
public class AutoActivationPluginProvider implements PluginProvider<PluginConfiguration> {
    
    private IgnitePredicate condition;
    private IgniteLogger logger;
    private Ignite grid;

    /**
     * Constructor
     * @param condition 
     */
    public AutoActivationPluginProvider(IgnitePredicate condition) {
        if (condition == null) {
            throw new IllegalArgumentException("condition must be set");
        }
        this.condition = condition;
    }
    
    @Override
    public String name() {
        return "AutoActivationPlugin";
    }

    @Override
    public <T extends IgnitePlugin> T plugin() {
        return (T) new AutoActivationPlugin();
    }

    @Override
    public String version() {
        return "0.1";
    }

    @Override
    public String copyright() {
        return "";
    }

    @Override
    public void initExtensions(PluginContext pc, ExtensionRegistry er) throws IgniteCheckedException {
        logger = pc.log(this.getClass());        
        grid = pc.grid();
    }

    @Override
    public <T> T createComponent(PluginContext pc, Class<T> type) {
        return null;
    }

    @Override
    public CachePluginProvider createCacheProvider(CachePluginContext cpc) {
        return null;
    }

    @Override
    public void start(PluginContext pc) throws IgniteCheckedException {
        // do nothing
    }

    @Override
    public void stop(boolean bln) throws IgniteCheckedException {
        // do nothing
    }

    @Override
    public void onIgniteStart() throws IgniteCheckedException {
    
        IgniteCluster cluster = grid.cluster();
        
        if (ClusterState.ACTIVE == cluster.state()) {
            if (logger.isInfoEnabled()) logger.info("Do nothing - cluster already activated");
            return;
        }

        if (cluster.currentBaselineTopology() != null) {
            if (logger.isInfoEnabled()) logger.info("Do nothing - baseline is not empty");
            return;
        }
        
        if (condition.apply(cluster.nodes())) {
            if (logger.isInfoEnabled()) logger.info("Activate cluster - activation condition meet");
            cluster.state(ClusterState.ACTIVE);
        } else {
            if (logger.isInfoEnabled()) logger.info("Do nothing = activation condition not meet");
        }
    }

    @Override
    public void onIgniteStop(boolean bln) {
        // do nothing
    }

    @Override
    public Serializable provideDiscoveryData(UUID uuid) {
        return null;
    }

    @Override
    public void receiveDiscoveryData(UUID uuid, Serializable srlzbl) {
        // do nothing
    }

    @Override
    public void validateNewNode(ClusterNode cn) throws PluginValidationException {
        // do nothing
    }
    
}
